/*      SClassHash.cpp
 *
 *      Copyright 2009 virpool <virpool@ukrpost.ua>
 *
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *      MA 02110-1301, USA.
 */

#include "SClassHash.h"

#include "SClassArray.h"
#include "SClassInteger.h"
#include "SClassFloat.h"
#include "SClassString.h"
#include "SClassBoolean.h"
#include "STypes.h"

SClassHash::SClassHash(string name) :
	SObject(name, "Hash")
{
	// TODO Auto-generated constructor stub
	GetMethods()->insert(pair<string, s_func> ("Add", &SClassHash::Add));
	GetMethods()->insert(pair<string, s_func> ("Remove", &SClassHash::Remove));
}

SClassHash::~SClassHash()
{
	// TODO Auto-generated destructor stub
}

int SClassHash::Add(SObject* obj, s_param* res, param_list* args)
{
	if (obj == NULL || args == NULL || args->size() != 2)
	{
		return S_INVOKE_INCORRECT;
	}
	param_list::iterator p = args->begin();
	switch (p->type)
	{
	case S_INT:
	case S_FLOAT:
	case S_ARRAY:
	case S_HASH:
	case S_BOOL:
		return S_INVOKE_INCORRECT;
	default:
		break;
	}
	string name = (*((string*) p->val));
	cerr << "in hash. key = " << name << endl;
	p++;
	SObject *nel = NULL;
	switch (p->type)
	{
	case S_OBJECT:
	{
		break;
	}
	case S_INT:
	{
		nel = new SClassInteger("none");
		((SClassInteger*) nel)->Set((*(int*) (*p).val));
		break;
	}
	case S_STRING:
	{
		nel = new SClassString("none");
		((SClassString*) nel)->Set((*(string*) (*p).val));
		break;
	}
	case S_BOOL:
	{
		nel = new SClassBoolean("none");
		((SClassBoolean*) nel)->Set((*(bool*) (*p).val));
		break;
	}
	}
	map<string, SObject*>::iterator mp = ((SClassHash*)obj)->hash.find(name);
	if (mp == ((SClassHash*)obj)->hash.end())
	{
		s_obj *varbl = new s_obj();
		varbl->obj = obj;
		varbl->clinks = 1;
		((SClassHash*)obj)->hash.insert(pair<string, SObject*> (name, nel));
		return S_ADD_VARIABLE_OK;
	}
	else
	{
		return S_VARIABLE_DUBLICATE;
	}
}

SObject* SClassHash::Get(string key)
{
	map<string, SObject*>::iterator mp = hash.find(key);
	if (mp == hash.end())
	{
		return NULL;
	}
	return mp->second;
}

int SClassHash::Remove(SObject* obj, s_param* res, param_list* args)
{
	param_list::iterator p = args->begin();
	string name = *((string*)p->val);
	map<string, SObject*>::iterator mp = ((SClassHash*)obj)->hash.find(name);
	if (mp == ((SClassHash*)obj)->hash.end())
	{
		return S_NO;
	}
	((SClassHash*)obj)->hash.erase(mp);
	return S_YES;
}
